package vacuum.lgadmin.monsterspawn;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Stack;

import org.bukkit.block.CreatureSpawner;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.CreatureType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;

import vacuum.lgadmin.LGAdmin;
import vacuum.lgadmin.LGPlugin;
import vacuum.lgadmin.utils.IOUtils;

public class MonsterSpawnPlugin extends LGPlugin
{
	//TODO conver commands to new system
	public MonsterSpawnPlugin(LGAdmin lga)
	{
		super(lga);
	}

	private HashMap<String, Stack<String>> playerToPlaceStack = new HashMap<String, Stack<String>>();

	private HashMap<String, String> playerToClick = new HashMap<String, String>();

	private File stacksFile;

	private File clicksFile;

	@Override
	public void onDisable()
	{
		try
		{
			IOUtils.writeHashMapStringStackString(stacksFile, playerToPlaceStack);
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		try
		{
			IOUtils.writeHashMapStringString(clicksFile, playerToClick);
		} catch (IOException e)
		{
			e.printStackTrace();
		}
		
		lga.getCommand("getSpawner").setExecutor(null);
		lga.getCommand("makeSpawner").setExecutor(null);
	}

	@Override
	public void onEnable()
	{
		
		log("Initializing files...");

		clicksFile = new File(getDataFolder() + File.separator + "clicks.txt");
		stacksFile = new File(getDataFolder() + File.separator + "stacks.txt");

		try
		{
			if(!stacksFile.exists()){
				stacksFile.getParentFile().mkdirs();
				stacksFile.createNewFile();
			}
			playerToPlaceStack = IOUtils.readHashMapStringStackString(stacksFile);
		} catch (IOException e)
		{
			e.printStackTrace();
		}

		try
		{
			if(!clicksFile.exists()){
				clicksFile.getParentFile().mkdirs();
				clicksFile.createNewFile();
			}
			playerToClick = IOUtils.readHashMapStringString(clicksFile);
		} catch (IOException e)
		{
			e.printStackTrace();
		}

		log("Initializing commands...");
		
		lga.getCommand("getSpawner").setExecutor(new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{
				if(sender instanceof ConsoleCommandSender && args.length == 1){
					sender.sendMessage("You can't use that command from the console!");
					return true;
				}
				if(args.length == 0 || args.length > 2)
					return false;
				Player p = (Player)sender;
				if(args.length == 2){
					p = lga.getServer().getPlayer(args[1]);
				}
				ItemStack stack = new ItemStack(52,1);
				p.getInventory().addItem(stack);
				if(!playerToPlaceStack.containsKey(p.getName().toLowerCase())){
					playerToPlaceStack.put(p.getName().toLowerCase(), new Stack<String>());
				}
				playerToPlaceStack.get(p.getName().toLowerCase()).push(args[0]);
				return true;
			}
		});

		lga.getCommand("makeSpawner").setExecutor(new CommandExecutor()
		{

			@Override
			public boolean onCommand(CommandSender sender, Command command,
					String label, String[] args)
			{
				if(sender instanceof ConsoleCommandSender && args.length == 1){
					sender.sendMessage("You can't use that command from the console!");
					return true;
				}
				if(args.length == 0 || args.length > 2)
					return false;
				Player p = (Player)sender;
				if(args.length == 2){
					p = lga.getServer().getPlayer(args[1]);
				}
				playerToClick.put(p.getName().toLowerCase(), args[0]);
				sender.sendMessage("Gave " + (p.equals(sender) ? "you" : p.getName()) + " the ability to place one (1) " + args[0] + " spawner");
				if(!(sender instanceof ConsoleCommandSender))
					log(sender.getName() + " gave " + (p.equals(sender) ? "themself" : p.getName()) + " the ability to place one (1) " + args[0] + " spawner");
				return true;
			}
		});
		
		log("Registering events...");

		lga.getServer().getPluginManager().registerEvents(new Listener()
		{

			@EventHandler(priority=EventPriority.NORMAL)
			public void onBlockPlace(BlockPlaceEvent event)
			{
				Player player = event.getPlayer();
				if(player != null && event.getBlock().getType().getId() == 52){
					Stack<String> stack = playerToPlaceStack.get(player.getName().toLowerCase());
					log(stack);
					log(playerToPlaceStack);
					if(stack != null){
						String str = stack.pop();
						log("Placing spawner of type " + str + ".");
						try{
							((CreatureSpawner)event.getBlock().getState()).setCreatureType(CreatureType.valueOf(str.toUpperCase()));
						} catch (Exception ex){
							ex.printStackTrace();
							player.sendMessage("There is no creature " + str + "; cannot create spawner.");
							log("There is no creature " + str + "; cannot create spawner for " + player.getName() + ".");
						}
						if(stack.isEmpty()){
							playerToPlaceStack.remove(player.getName());
						}
					}
				}
			}
			
			@EventHandler(priority=EventPriority.NORMAL)
			public void onPlayerDropItem(PlayerDropItemEvent event)
			{
				if(event.getItemDrop().getItemStack().getTypeId() == 52){
					Player p = event.getPlayer();
					Stack<String> stack = playerToPlaceStack.get(p.getName());
					if(stack != null){
						for(int i = 0; i < event.getItemDrop().getItemStack().getAmount(); i++){
							String str = stack.pop();
							log(p.getName() + " dropped their " + str.toLowerCase() + " spawner. Destroying item.");
							p.sendMessage("Destroying your " + str.toLowerCase() + " spawner.");
						}
						event.getItemDrop().remove();
					}
				}
			}
			
			@EventHandler(priority=EventPriority.NORMAL)
			public void onPlayerInteract(PlayerInteractEvent event)
			{
				Player p = event.getPlayer();
				String s;
				if(event.getAction().equals(Action.LEFT_CLICK_BLOCK) && p != null && (s = playerToClick.get(p.getName().toLowerCase())) != null){
					playerToClick.remove(p.getName().toLowerCase().toString());
					event.getClickedBlock().setTypeId(52);
					log("Set block data");
					try{
						((CreatureSpawner)event.getClickedBlock().getState()).setCreatureTypeByName(s.toUpperCase());
					} catch (Exception ex){
						ex.printStackTrace();
						p.sendMessage("There is no creature " + s + "; cannot create spawner.");
						log("There is no creature " + s + "; cannot create spawner for " + p.getName() + ".");
					}
				}
			}

		}, lga);
	}

	@Override
	public String getName()
	{
		return "LGMonsterSpawn";
	}

	@Override
	public String getVersion()
	{
		return "1.1.4";
	}

}
